/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
//		File Name		:		CGame.h
//
//		Author			:		Vindicated Games
//
//		Purpose			:		Be the main vein for the game
//
//		Dates			:		Written( Feb 12, 2011 ) by Vindicated Games		LastUpdate( Feb 12, 2011  ) by Vindicated Games 
//	
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#include "CGame.h"
#include "../Managers/ParticleManager.h"
#include "../Game States/CMainMenuState.h"
#include "../Game States/CGamePlayState.h"
#include "../Game States/COptionsState.h"
#include "../Managers/VIN_ObjectManager.h"
#include "../SGD wrappers/CSGD_FModManager.h"
#include "../Managers/InputManager.h"
#include "VIN_EventSystem.h"
#include "MessageSystem.h"
#include <ctime>

#include "../Visual/VIN_BitMapFont.h"

#include <ctime>


CGame::CGame()
{
	//Pointers to NULL
	m_pD3D	= NULL;
	m_pTM	= NULL;
	m_pDS	= NULL;
	m_pFM	= NULL;
	m_pDI	= NULL;
	m_pGS	= NULL;
	m_pOM	= NULL;
	//	m_pES	= NULL;

	ActiveProfile.SetCombat(1);
	ActiveProfile.SetDurability(1);
	ActiveProfile.SetHealth(100);
	ActiveProfile.SetCash(1);
	ActiveProfile.SetRage(1);
	ActiveProfile.SetSpeed(1);
}


CGame::~CGame()
{



}

CGame* CGame::GetInstance()
{
	static CGame instance;
	return &instance;

}


bool CGame::Main()
{
	//////////////////////////////////////////////////////////////////////
	//							Time Step Update								//
	//////////////////////////////////////////////////////////////////////
	DWORD dwStartTimeStamp = GetTickCount();																					    /**/
	m_fElapsedTime = (float)(dwStartTimeStamp - m_dwPreviousTimeStamp) / 1000.0f;																							    
	m_dwPreviousTimeStamp = dwStartTimeStamp;
	//////////////////////////////////////////////////////////////////////

	if( Input() == false )
		return false;
	Update(m_fElapsedTime);

	Render();

	//FPS Counting
	m_nFrameCount++;

	if (GetTickCount() - m_dwFPSTimeStamp > 1000)
	{
		//	remember the frame count
		m_nFPS = m_nFrameCount;
		//	reset the frame count
		m_nFrameCount = 0;
		//	get a new time stamp
		m_dwFPSTimeStamp = GetTickCount();
	}

	return true;
}

bool CGame::Input()
{
	m_pDI->ReadDevices();

	if((CSGD_DirectInput::GetInstance()->KeyDown(DIK_RALT) || CSGD_DirectInput::GetInstance()->KeyDown(DIK_LALT)) && CSGD_DirectInput::GetInstance()->KeyPressed(DIK_RETURN))
	{
		CSGD_DirectInput::GetInstance()->ReadDevices();

		bool windowedTemp= !CSGD_Direct3D::GetInstance()->GetPresentParams()->Windowed;
		CGamePlayState::GetInstance()->SetPause(true);
		CSGD_Direct3D::GetInstance()->ChangeDisplayParam(CSGD_Direct3D::GetInstance()->GetPresentParams()->BackBufferWidth, 
				CSGD_Direct3D::GetInstance()->GetPresentParams()->BackBufferHeight,windowedTemp);
	}

	if((CSGD_DirectInput::GetInstance()->KeyDown(DIK_RALT) || CSGD_DirectInput::GetInstance()->KeyDown(DIK_LALT)) && CSGD_DirectInput::GetInstance()->KeyPressed(DIK_TAB))
		CGamePlayState::GetInstance()->SetPause(true);

	
	if(!m_pGS->Input())
		return false;



	return true;
}


void CGame::ChangeState( IBaseState* pNewState )
{

	if( m_pGS )
	{
		m_pGS->Exit();
		m_pGS = NULL;
	}

	m_pGS = pNewState;

	if( m_pGS )
	{
		m_pGS->Enter();
	}
}


void CGame::GameInit(HWND hWnd, HINSTANCE hInstance, int nScreenWidth, int nScreenHeight, bool bIsWindowed)
{	
	m_pD3D	= CSGD_Direct3D::GetInstance();
	m_pD3D->InitDirect3D(hWnd, nScreenWidth, nScreenHeight, bIsWindowed, true);

	m_pTM	= CSGD_TextureManager::GetInstance();
	m_pTM->InitTextureManager( m_pD3D->GetDirect3DDevice(), m_pD3D->GetSprite() );

	m_pD3D->Clear(0,0,0);
	m_pD3D->DeviceBegin();
	m_pD3D->SpriteBegin();

	 LoadID = m_pTM->LoadTexture("resources/graphics/loading.png");
	 m_pTM->Draw(LoadID, 0, 0);

	m_pD3D->SpriteEnd();
	m_pD3D->DeviceEnd();
	m_pD3D->Present();

	// SEED THE RANDOM NUMBER GENERATOR
	srand(unsigned int(time(0)));

	//Get pointers to the respective singletons
	m_pDS	= CSGD_DirectSound::GetInstance();
	m_pFM	= CSGD_FModManager::GetInstance();
	m_pSM	= VIN_SoundManager::GetInstance();
	m_pDI	= CSGD_DirectInput::GetInstance();
	m_pOM	= VIN_ObjectManager::GetInstance();



	//Init all the singletons so that they are full 'stead of empty

	m_pFM->InitFModManager(hWnd, 1024);
	m_pDS->InitDirectSound(hWnd);
	//m_pDI->InitDirectInput(hWnd, hInstance, DI_KEYBOARD | DI_JOYSTICKS );
	InputManager::GetInstance()->Init(hWnd, hInstance);

	ParticleManager::GetInstance()->Init();

	MessageSystem::GetInstance()->Init();


	m_pSM->Startup();
	VIN_BitMapFont::GetInstance()->Startup();
	ChangeState( CMainMenuState::GetInstance() );
}


void CGame::ShutDown()
{

	ChangeState(NULL);

	//MessageSystem::GetInstance()->Shutdown();


	if(	m_pDI )
	{
		m_pDI->ShutdownDirectInput();
	}

	if(	m_pDS )
	{
		m_pDS->ShutdownDirectSound();
	}
	if(	m_pTM )
	{
		m_pTM->ShutdownTextureManager();
	}
	if( m_pD3D )
	{
		m_pD3D->ShutdownDirect3D();
	}
	if( m_pOM )
	{
		m_pOM->ShutDown();
	}	

	InputManager::GetInstance()->Shutdown();
	ParticleManager::GetInstance()->Shutdown();
}

void CGame::Render()
{
	m_pD3D->Clear(255,255,255);
	m_pD3D->DeviceBegin();
	m_pD3D->SpriteBegin();

	if( m_pGS )
	{	
		 m_pGS->Render();
	}

	m_pD3D->SpriteEnd();
	m_pD3D->DeviceEnd();
	m_pD3D->Present();
}


void CGame::Update(float fElapsedTime)
{
	CSGD_FModManager::GetInstance()->Update();
	COptionsMenu::GetInstance()->Update(fElapsedTime);
//	VIN_SoundManager::GetInstance()->SetBGMVolume(COptionsMenu::GetInstance()->GetBgm());
//	VIN_SoundManager::GetInstance()->SetSFXVolume(COptionsMenu::GetInstance()->GetSfx());
	
	VIN_EventSystem::GetInstance()->ProcessEvents();
	if( m_pGS )
	{
		m_pGS->Update(m_fElapsedTime);
	}

	InputManager::GetInstance()->Update(fElapsedTime);
	ParticleManager::GetInstance()->Update(fElapsedTime);
}

CPlayerProfile* CGame::GetActiveSave()
{
	return &ActiveProfile;
}

void CGame::FillProfile( int Health, int Combat, int Durability, int Speed, int Rage, int Cash)
	{ 
		/*ActiveProfile.SetHealth( Health );
		ActiveProfile.SetCombat( Combat );
		ActiveProfile.SetDurability( Durability );
		ActiveProfile.SetSpeed( Speed );
		ActiveProfile.SetRage( Rage );
		ActiveProfile.SetCash( Cash );*/
		
	}